AWS Step FunctionsでMicrosoft Teamsに通知してみた
はじめに
AWS Step Functionsを使ってMicrosoft Teamsに通知する方法について、構築手順をまとめました。
Step Functionsを使うことで、柔軟なワークフローを組み立てながら、Teams通知を組み込めるところが利点です。
利用ケースとしては、以下が考えられます。
- 障害検知時にTeamsに通知し、メンバーにメンションを飛ばす
- バッチ処理の完了をTeamsに通知する
通知画面は以下のイメージです。メンションを飛ばしています。
全体の構成は以下の通りです。HTTPタスクを利用してTeamsに通知します。
今回はStep Functionsを起点にMicrosoft Teamsに通知しますが、他のサービスからStep Functions経由で通知することも可能です。
Step Functionsを呼び出すことができるAWSサービスには、以下のようなものがあります。
- AWS Lambda (StartExecution API を使用)
- Amazon API Gateway
- Amazon EventBridge
- AWS CodePipeline
- AWS IoT ルールエンジン
- AWS Step Functions
Amazon EventBridge の一機能である Amazon EventBridge Pipes でも、ターゲットをStep Functionsに設定することが可能です。
ソースは以下が選択できます。
- Amazon DynamoDB Streams
- Amazon Kinesis Data Streams
- Amazon MQ broker
- Amazon MSK stream
- Amazon SQS queue
- Apache Kafka Streams
以上のように、様々なAWSサービスからStep Functionsを呼び出すことができます。
HTTPタスク
HTTPタスクは、Step Functionsの機能の1つで、Microsoft TeamsやSalesforceなどのサードパーティのAPIを直接呼び出すことができます。
HTTPタスクでは、API呼び出しの認証情報をEventBridge 接続で管理できるため、シークレットをステートマシン定義にハードコーディングすることを避けられます。
HTTPタスクを使用すると、以下のようなメリットがあります。
- ステートマシン内から直接外部APIを呼び出せるため、Lambda関数を介さずにシンプルな構成にできる
- API呼び出しの認証情報をEventBridge 接続で管理できるため、シークレットをステートマシン定義にハードコーディングすることを避けられる
- リクエストとレスポンスのデータ変換や、リトライ、エラー処理などステートマシン内を柔軟に設定できる
HTTPタスクを使ったサードパーティAPI連携の全体の流れは以下のようになります。
- EventBridge 接続を作成し、API認証情報を設定する
- ステートマシン定義にHTTPタスクを追加し、APIエンドポイント、メソッド、ヘッダー、リクエスト本文などを設定する
- ステートマシンを実行すると、HTTPタスクがEventBridge 接続の認証情報を使ってAPIを呼び出す
- APIレスポンスはHTTPタスクの出力として後続のステートに渡される
このようにHTTPタスクを使うことで、Step FunctionsからサードパーティAPIを直接呼び出すことができます。
次節以降で、Microsoft TeamsへのWebhook通知を例に、具体的な実装方法を見ていきましょう。
TeamsのWebhookURLを取得
Teamsのチームの作成とWebhookURLの取得方法は以下の記事をご参考ください。
EventBridge 接続を作成
EventBridge 接続では、API キー名をContent-Type
、キーの値をapplication/json
と指定して作成します。
作成すると、EventBridge 接続の情報を保存するSecrets Managerのシークレットが自動作成されます。
Step Functions ステートマシンを作成
フローには、Call third-party API
のみを挿入します。
[設定]タブで以下の設定を行います。[入力]や[出力]、[エラー処理]タブはデフォルトのままです。
- API エンドポイント:TeamsのWebhookURL
- メソッド:POST
- Authentication:EventBridge 接続
リクエスト本文は以下のとおりです。
{ "type": "message", "attachments": [ { "contentType": "application/vnd.microsoft.card.adaptive", "content": { "type": "AdaptiveCard", "body": [ { "type": "TextBlock", "text": "<at>平井裕二</at>", "weight": "bolder", "size": "medium" }, { "type": "TextBlock", "text": "アラートを検知しました", "size": "Large", "weight": "Bolder" }, { "type": "Table", "columns": [ { "width": 1 }, { "width": 2 } ], "rows": [ { "type": "TableRow", "cells": [ { "type": "TableCell", "items": [ { "type": "TextBlock", "text": "項目", "weight": "Bolder" } ] }, { "type": "TableCell", "items": [ { "type": "TextBlock", "wrap": true, "text": "内容" } ] } ] }, { "type": "TableRow", "cells": [ { "type": "TableCell", "items": [ { "type": "TextBlock", "text.$": "$.item", "weight": "Bolder" } ] }, { "type": "TableCell", "items": [ { "type": "TextBlock", "wrap": true, "text.$": "$.content" } ] } ] } ] } ], "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.5", "msteams": { "width": "full", "entities": [ { "type": "mention", "text": "<at>平井裕二</at>", "mentioned": { "id": "xxx@example.com", "name": "平井 裕二" } } ] } } } ] }
Incoming WebhookでTeamsにメンション付きで通知するには、アダプティブカード形式で通知する必要がありますので、type
をAdaptiveCard
に設定します。
リクエスト本文のid
とname
は、メンション対象者に応じて変更してください。
id
:ユーザーのメールアドレス(xxxx@example.com)を指定name
:ユーザー名(ユーザー名)を指定
メンションするには、ユーザー名を<at></at>
で囲む必要があります
設定に遷移し、ステートマシン名を入力し、タイプは標準にします。また、実行ロールを[新しいロールを作成]にすると、先程選択したEventBridge 接続リソースに対するポリシーも自動作成されます。
ステートマシンの[作成]クリックすると、ステートマシン用のIAMロールのアクセス許可内容が確認できます。確認後、作成します。
ステートマシンのIAMロール
ステートマシンのIAMロールには以下の3つのポリシーが適用されていました。 3つのポリシーとも名前にランダムな文字列が含まれていますが、それぞれ異なる文字列です。
- EventBridgeRetrieveConnectionCredentialsScopedAccessPolicy-[ランダム文字列]
- EventBridge接続の認証情報を取得するためのポリシー
- StepFunctionsInvokeHttpEndpointScopedAccessPolicy-[ランダム文字列]
- HTTPタスクでTeamsのWebhookURLを呼び出すためのポリシー
- XRayAccessPolicy-e012773e-dbcb-4a75-bee1-cbfc4e404683-[ランダム文字列]
- X-Rayでトレースを行うためのポリシー
EventBridgeRetrieveConnectionCredentialsScopedAccessPolicy-[ランダム文字列]ポリシーの内容は以下の通りです。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Sid": "RetrieveConnectionCredentials1", "Action": [ "events:RetrieveConnectionCredentials" ], "Resource": [ "arn:aws:events:ap-northeast-1:xxxxxxxxxxxx:connection/stepfunctions-notify-teams/*" ] }, { "Effect": "Allow", "Sid": "GetAndDescribeSecretValue1", "Action": [ "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret" ], "Resource": [ "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:events!connection/stepfunctions-notify-teams/*" ] } ] }
StepFunctionsInvokeHttpEndpointScopedAccessPolicy-[ランダム文字列]ポリシーの内容は以下の通りです。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Sid": "InvokeHttpEndpoint1", "Action": [ "states:InvokeHTTPEndpoint" ], "Resource": [ "arn:aws:states:ap-northeast-1:xxxxxxxxxxxx:stateMachine:*" ], "Condition": { "StringEquals": { "states:HTTPEndpoint": [ "WebhookURLの値" ], "states:HTTPMethod": [ "POST" ] } } } ] }
XRayAccessPolicy-e012773e-dbcb-4a75-bee1-cbfc4e404683-[ランダム文字列]
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "xray:PutTraceSegments", "xray:PutTelemetryRecords", "xray:GetSamplingRules", "xray:GetSamplingTargets" ], "Resource": [ "*" ] } ] }
EventBridge接続、シークレット、WebhookURLがIAMポリシーに指定されているため、ステートマシン内のこれらの値を変更する場合は、IAMポリシーもあわせて修正する必要があります。
テスト
[実行を開始]をクリックします。実行の入力値は以下です。
{ "item": "test", "content": "hoge" }
以下のアクセス許可エラーが発生しました。
AWS Step Functions is not authorized to perform states:InvokeHTTPEndpoint on API Endpoint https://xxx.webhook.office.com/webhookb2/xxx. Ensure that the StateMachine role contains the states:InvokeHTTPEndpoint permission for the given API Endpoint
WebhookURLには@
が含まれていましたが、エラーメッセージでは@
が%40
にURLエンコードされていました。
そのため、ステートマシンのIAMポリシーで指定するWebhookURLの@
を%40
に置き換えました。
置き換え後、再度実行すると、通知できていることが確認できました。
最後に
AWS Step FunctionsでMicrosoft Teamsに通知する構築方法を紹介しました。
柔軟なワークフローを組み立てながら、Teams通知を組み込めるのがStep Functionsの利点です。ぜひ活用してみてください。